/**
 * Ingenius-Group S.A.S
 *
 * Project: SAU
 * File: EditSelfEvaluationPresenter.java
 * Date: 02/03/2011
 */

package com.ingenius.sau.client.presenter;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;

import com.google.gwt.core.client.GWT;
import com.google.gwt.event.shared.HandlerManager;
import com.google.gwt.user.client.rpc.AsyncCallback;
import com.google.gwt.user.client.ui.HasWidgets;
import com.ingenius.sau.client.AppController;
import com.ingenius.sau.client.Constants;
import com.ingenius.sau.client.event.ListSelfEvaluationsEvent;
import com.ingenius.sau.client.service.CoreServiceAsync;
import com.ingenius.sau.client.view.Display;
import com.ingenius.sau.shared.model.core.Scale;
import com.ingenius.sau.shared.model.core.SelfEvaluation;
import com.ingenius.sau.shared.model.guidelines.Guideline;
import com.ingenius.sau.shared.model.programs.AcademicProgram;

/**
 * Class <strong>EditSelfEvaluationPresenter</strong>
 * 
 * @author Jesus David
 * @version 0.1
 */
public class EditSelfEvaluationPresenter implements EditPresenter {

	public interface EditSelfEvaluationDisplay extends Display {

		String getName();

		void setName(String name);

		String getDescription();

		void setDescription(String description);

		String getAcademicProgramId();

		void setAcademicProgramId(String programId);

		void setAcademicPrograms(List<AcademicProgram> programs);

		String getGuidelinesId();

		void setGuidelinesId(String guidelinesId);

		void setGuidelines(List<Guideline> guidelines);

		String getEvaluationState();

		void setEvaluationState(String state);

		void setEvaluationStates(List<String> states);

		String getScaleId();

		void setScaleId(String scaleId);

		void setScales(List<Scale> scales);

		Date getStartDate();

		void setStartDate(Date startDate);

		Date getDeliveryDate();

		void setDeliveryDate(Date deliveryDate);

		void show();

		void hide();

	}

	private final HandlerManager eventBus;
	private final CoreServiceAsync rpcService;
	private final EditSelfEvaluationDisplay display;
	private SelfEvaluation evaluation;

	public EditSelfEvaluationPresenter(HandlerManager eventBus,
			CoreServiceAsync rpcService, EditSelfEvaluationDisplay display,
			String evaluationId) {

		this.rpcService = rpcService;
		this.eventBus = eventBus;
		this.display = display;
		display.setPresenter(this);
		loadPrograms();
		loadGuidelines();
		loadEvaluationStates();
		loadScales();

		if (evaluationId == null) {
			evaluation = new SelfEvaluation();
			display.setEvaluationState(SelfEvaluation.ACTIVE);

		} else {
			loadBean(evaluationId);
		}

	}

	private void loadPrograms() {
		rpcService.loadAllPrograms(new AsyncCallback<List<AcademicProgram>>() {
			@Override
			public void onSuccess(List<AcademicProgram> result) {
				display.setAcademicPrograms(result);
			}

			@Override
			public void onFailure(Throwable caught) {
				System.out.println("Error loading programs. "
						+ caught.getMessage());
			}
		});
	}

	private void loadGuidelines() {
		rpcService.loadAllGuidelines(new AsyncCallback<List<Guideline>>() {
			@Override
			public void onSuccess(List<Guideline> result) {
				display.setGuidelines(result);
			}

			@Override
			public void onFailure(Throwable caught) {
				System.out.println("Error loading guidelines. "
						+ caught.getMessage());
			}
		});
	}

	private void loadEvaluationStates() {
		List<String> states = new ArrayList<String>();
		states.add(SelfEvaluation.ACTIVE);
		states.add(SelfEvaluation.INACTIVE);
		display.setEvaluationStates(states);
	}

	private void loadScales() {
		rpcService.loadAllScales(new AsyncCallback<List<Scale>>() {
			@Override
			public void onSuccess(List<Scale> result) {
				display.setScales(result);
			}

			@Override
			public void onFailure(Throwable caught) {
				System.out.println("Error loading scales. "
						+ caught.getMessage());
			}
		});
	}

	private void loadBean(String evaluationId) {
		AppController.setStatusMessage("Loading...");
		rpcService.getSelfEvaluation(evaluationId,
				new AsyncCallback<SelfEvaluation>() {
					@Override
					public void onSuccess(SelfEvaluation result) {
						if (result == null) {
							onFailure(new Throwable("Database error"));
							return;
						}
						evaluation = result;
						display.setDeliveryDate(evaluation.getDeliveryDate());
						display.setDescription(evaluation.getDescription());
						display.setName(evaluation.getName());
						display.setStartDate(evaluation.getStartDate());
						display.setEvaluationState(evaluation.getState());
						display.setAcademicProgramId(evaluation
								.getAcademicProgram().getId());
						display.setGuidelinesId(evaluation.getGuidelineId());
						display.setScaleId(evaluation.getScaleId());
						hideStatusMessage();
					}

					@Override
					public void onFailure(Throwable caught) {
						GWT.log(Constants.MESSAGE_FAILED_GET
								+ SelfEvaluation.class.getName(), caught);
						evaluation = new SelfEvaluation();
						// TODO i18n
						String failedMessage = "Failed to retrieve self evaluation";
						display.showInfo(failedMessage);
						hideStatusMessage();
					}

					void hideStatusMessage() {
						AppController.hideStatusMessage();
					}
				});
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see com.ingenius.sau.client.presenter.EditPresenter#doSaveOrUpdate()
	 */
	@Override
	public void doSaveOrUpdate() {
		evaluation.setDeliveryDate(display.getDeliveryDate());
		evaluation.setDescription(display.getDescription());
		evaluation.setName(display.getName());
		evaluation.setStartDate(display.getStartDate());
		evaluation.setState(display.getEvaluationState());
		evaluation.setGuidelineId(display.getGuidelinesId());
		evaluation.setScaleId(display.getScaleId());
		evaluation.setAcademicProgram(new AcademicProgram(display
				.getAcademicProgramId()));

		// TODO i18n
		final String failedMessage = "Failed to save self evaluation";
		final String successMessage = "Self evaluation saved sucessfully";

		display.hide();
		AppController.setStatusMessage("Saving...");
		rpcService.saveOrUpdateSelfEvaluation(evaluation,
				new AsyncCallback<Boolean>() {
					@Override
					public void onSuccess(Boolean result) {
						if (result) {
							eventBus.fireEvent(new ListSelfEvaluationsEvent());
							display.showInfo(successMessage);
							hideStatusMessage();

						} else {
							onFailure(new Throwable("Database error"));
						}
					}

					@Override
					public void onFailure(Throwable caught) {
						GWT.log(Constants.MESSAGE_FAILED_SAVE
								+ SelfEvaluation.class.getName(), caught);
						display.showInfo(failedMessage);
						hideStatusMessage();
					}

					void hideStatusMessage() {
						AppController.hideStatusMessage();
					}
				});
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see
	 * com.ingenius.sau.client.presenter.Presenter#go(com.google.gwt.user.client
	 * .ui.HasWidgets)
	 */
	@Override
	public void go(HasWidgets container) {
		display.show();
	}

}
